package repository

import (
	"django_blog_gin/internal/dto"
	"django_blog_gin/internal/model"
	"django_blog_gin/internal/svc"
	"fmt"
)

type TagRepo struct {
	svcCtx *svc.ServiceContext
}

func NewTagRepo(svcCtx *svc.ServiceContext) *TagRepo {
	return &TagRepo{svcCtx: svcCtx}
}

func (r *TagRepo) GetTagTotal() (int, error) {
	var total int
	sql := fmt.Sprintf(`
        SELECT 
            COUNT(*)
        FROM %s
    `, model.BlogTag{}.TableName())
	err := r.svcCtx.MysqlDb.Get(&total, sql)
	if err != nil {
		return 0, err
	}
	return total, nil
}

func (r *TagRepo) GetTagList(limit string, offset string, name string) ([]model.BlogTag, int, error) {
	// 需要添加total
	tagList := []model.BlogTag{}
	total, err := r.GetTagTotal()
	if err != nil {
		return tagList, 0, err
	}
	sql := fmt.Sprintf(`
        SELECT 
            id,
            name,
            slug,
            created_time,
            last_mod_time
        FROM %s
    `, model.BlogTag{}.TableName())

	var args []interface{}
	if name != "" {
		sql += " WHERE name LIKE ?"
		args = append(args, "%"+name+"%")
	}
	sql += " LIMIT ? OFFSET ?"
	args = append(args, limit, offset)

	err = r.svcCtx.MysqlDb.Select(&tagList, sql, args...)
	if err != nil {
		return tagList, 0, err
	}
	return tagList, total, nil
}

// 创建标签
func (r *TagRepo) CreateTag(req *dto.CretaeTagReq) error {
	sql := fmt.Sprintf(`
        INSERT INTO %s (name, slug, created_time, last_mod_time)
        VALUES (:name, :slug, NOW(), NOW())
    `, model.BlogTag{}.TableName())
	_, err := r.svcCtx.MysqlDb.NamedExec(sql, req)
	if err != nil {
		return err
	}
	return nil
}

// 查询标签name是否已经存在
func (r *TagRepo) CheckTagExist(name string) (bool, error) {
	var count int
	sql := fmt.Sprintf(`
        SELECT COUNT(*) FROM %s WHERE name = ?
    `, model.BlogTag{}.TableName())
	err := r.svcCtx.MysqlDb.Get(&count, sql, name)
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// 通过name查询标签
func (r *TagRepo) GetTagByName(name string) (*model.BlogTag, error) {
	tag := &model.BlogTag{}
	sql := fmt.Sprintf(`
        SELECT 
            id,
            name,
            slug
        FROM %s
        WHERE name = ?
    `, model.BlogTag{}.TableName())
	err := r.svcCtx.MysqlDb.Get(tag, sql, name)
	if err != nil {
		return tag, err
	}
	return tag, nil
}

func (r *TagRepo) UpdateTag(req *dto.UpdateTagReq) error {
	sql := fmt.Sprintf(`
        UPDATE %s SET name = :name, slug = :slug, index = :index, last_mod_time = NOW() WHERE id = :id
    `, model.BlogTag{}.TableName())
	_, err := r.svcCtx.MysqlDb.NamedExec(sql, req)
	if err != nil {
		return err
	}
	return nil
}

func (r *TagRepo) SearchTagWithId(id int) ([]model.BlogTag, error) {
	tagList := []model.BlogTag{}
	tagSql := fmt.Sprintf(`
		SELECT 
			id,
			name
		FROM %s
		WHERE id IN (
			SELECT tag_id FROM %s WHERE article_id = %d
		)
	`, model.BlogTag{}.TableName(), model.BlogArticleTags{}.TableName(), id)
	err := r.svcCtx.MysqlDb.Select(&tagList, tagSql)
	if err != nil {
		return nil, err
	}
	return tagList, nil
}
